package com.ruoyi.web.core.config.mqtt;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.java_websocket.server.WebSocketServer;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.CacheUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.crc.HexUtil;
import com.ruoyi.system.service.ICommonService;
import com.ruoyi.web.core.config.SystemConfig;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author chmj
 * @version V1.0
 * @Package com.radar.util.mqtt
 * @Copyright 2022/9/13 16:51 汇博医疗股份有限公司
 */
@Slf4j
@Component
public class MessageListener implements IMqttMessageListener {

    @Autowired
    private ICommonService commonService;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    public static MessageListener messageListener;

    @PostConstruct
    public void init() {

        messageListener = this;
        messageListener.commonService = this.commonService;
        messageListener.messagingTemplate = this.messagingTemplate;
    }

    /**
     * 处理消息
     * @param topic 主题
     * @param message 消息
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) {
        log.info("[接收消息主题]:{}", topic);
        log.info("[接收消息Qos]:{}", message.getQos());
//        log.info("[接收消息内容]:{}", HexUtil.bytes2HexString(message.getPayload()));
        log.info("[接收消息retained]:{}", message.isRetained());
        String deviceCode = topic.substring(topic.indexOf("Radar60SP/") + 10,topic.indexOf("/sys"));
        String dataKey = null;
        String dataValue = null;
        String m = new String(message.getPayload());
        if(m.indexOf("params") != -1){
            log.info("[接收消息内容]:{}", m);
            JSONObject jsonObject = JSONObject.parseObject(new String(message.getPayload()));
            Map<String,Object> paramsMap = JSONObject.parseObject(jsonObject.getString("params"));
            for(String key:paramsMap.keySet()){
                dataKey = key;
                dataValue = paramsMap.get(key).toString();
            }
        }else{
            String msg = HexUtil.bytes2HexString(message.getPayload());
            log.info("[接收消息内容]:{}", msg);
            if(msg.startsWith("53 59 ") || msg.endsWith("54 43 ")){
                msg = msg.replace(" ","");
                String control = msg.substring(4,6);
                String command = msg.substring(6,8);
                String data = msg.substring(12,msg.length() - 6);
                switch (control){
                    case "01":
                        log.info("心跳包");
                        break;
                    case "02":
                        log.info("产品信息");
                        break;
                    case "03":
                        log.info("OTA升级");
                        break;
                    case "05":
                        log.info("工作状态");
                        break;
                    case "07":
                        log.info("雷达探测范围信息");
                        break;
                    case "80":
                        switch (command){
                            case "01":
                                log.info("存在信息");
                                dataKey = "someoneExists";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "02":
                                log.info("运动信息");
                                dataKey = "motionStatus";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "03":
                                log.info("体动参数");
                                dataKey = "movementSigns";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "04":
                                log.info("人体距离");
                                dataKey = "humanDistance";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "05":
                                log.info("人体方位");
                                dataKey = "humanPosition";
                                String x = Integer.parseInt(data.substring(0,4),16) + "";
                                String y = Integer.parseInt(data.substring(4,8),16) + "";
                                String z = Integer.parseInt(data.substring(8,12),16) + "";
                                Map<String,Object> humanPosition = new HashMap<>();
                                humanPosition.put("x",x);
                                humanPosition.put("y",y);
                                humanPosition.put("z",z);
                                dataValue = JSONObject.toJSONString(humanPosition);
                                break;
                            case "81":
                                log.info("存在信息");
                                break;
                            case "82":
                                log.info("运动信息");
                                break;
                            case "83":
                                log.info("体动参数");
                                break;
                            case "84":
                                log.info("人体距离");
                                break;
                            case "85":
                                log.info("人体方位");
                                break;
                        }
                        break;
                    case "81":
                        switch (command){
                            case "01":
                                log.info("呼吸信息");
                                dataKey = "breathInform";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "02":
                                log.info("呼吸数值");
                                dataKey = "breathValue";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "05":
                                log.info("呼吸波形");
                                dataKey = "breathWave";
                                Integer[] breathWave = new Integer[5];
                                for (int i = 0; i < breathWave.length; i++) {
                                    breathWave[i] = Integer.parseInt(data.substring(i*2,i*2+2),16);
                                }
                                dataValue = String.valueOf(breathWave);
                                break;
                            case "81":
                                log.info("呼吸信息");
                                break;
                            case "82":
                                log.info("呼吸数值");
                                break;
                            case "85":
                                log.info("呼吸波形");
                                break;
                        }
                        break;
                    case "84":
                        switch (command){
                            case "01":
                                log.info("入床/离床状态");
                                dataKey = "getIntoBed";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "02":
                                log.info("睡眠状态");
                                dataKey = "sleepStatus";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "03":
                                log.info("清醒时长");
                                dataKey = "awakeDuration";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "04":
                                log.info("浅睡时长");
                                dataKey = "lightSleepDuration";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "05":
                                log.info("深睡时长");
                                dataKey = "deepSleepDuration";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "06":
                                log.info("睡眠质量评分");
                                dataKey = "sleepScore";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "0C":
                                log.info("睡眠综合状态");
                                dataKey = "sleepComprehensiveStatus";
                                break;
                            case "0D":
                                log.info("睡眠质量分析");
                                dataKey = "sleepQualityAnalysis";
                                break;
                            case "0E":
                                log.info("睡眠异常");
                                dataKey = "abnormalSleep";
                                break;
                            case "0F":
                                log.info("上报模式");
                                dataKey = "reportMode";
                                break;
                            case "81":
                                log.info("入床/离床状态");
                                break;
                            case "82":
                                log.info("睡眠状态");
                                break;
                            case "83":
                                log.info("清醒时长");
                                break;
                            case "84":
                                log.info("浅睡时长");
                                break;
                            case "85":
                                log.info("深睡时长");
                                break;
                            case "86":
                                log.info("睡眠质量评分");
                                break;
                            case "8C":
                                log.info("上报模式");
                                break;
                            case "8D":
                                log.info("睡眠综合状态");
                                break;
                            case "8E":
                                log.info("睡眠异常");
                                break;
                            case "8F":
                                log.info("睡眠统计");
                                break;
                        }
                        break;
                    case "85":
                        switch (command){
                            case "02":
                                log.info("心率数值");
                                dataKey = "heartRateValue";
                                dataValue = Integer.parseInt(data,16) + "";
                                break;
                            case "05":
                                log.info("心率波形");
                                dataKey = "heartRateWave";
                                Integer[] heartRateWave = new Integer[5];
                                for (int i = 0; i < heartRateWave.length; i++) {
                                    heartRateWave[i] = Integer.parseInt(data.substring(i*2,i*2+2),16);
                                }
                                dataValue = String.valueOf(heartRateWave);
                                break;
                            case "82":
                                log.info("心率数值");
                                break;
                            case "85":
                                log.info("心率波形");
                                break;
                        }
                        break;
                }
            }
        }
        if(StringUtils.isNotNull(dataKey) && StringUtils.isNotNull(dataValue)){
            messageListener.commonService.saveRadarData(deviceCode, dataKey, dataValue, new Date());
        }
        Map<String, Object> map = new HashMap<>();
        map.put("deviceCode", deviceCode);
        if(dataKey.equals("heartRateValue")){
            Integer heartRateValue = Integer.parseInt(dataValue);
            if(heartRateValue > 30){
                map.put("key", "someoneExists");
                map.put("value", 1);
            }else{
                map.put("key", "someoneExists");
                map.put("value", 0);
            }
            messageListener.messagingTemplate.convertAndSendToUser("radars", "/message", map);
        }
        if(dataKey.equals("sleepStatus")){
            if(dataValue.equals("0")){
                dataValue = "深睡";
            }else if(dataValue.equals("1")){
                dataValue = "浅睡";
            }else if(dataValue.equals("2")){
                dataValue = "清醒";
            }else{
                dataValue = "无";
            }
        }
        if(dataKey.equals("motionStatus")){
            if(dataValue.equals("1")){
                dataValue = "静止";
            }else if(dataValue.equals("2")){
                dataValue = "活跃";
            }else{
                dataValue = "无";
            }
        }
        if(dataKey.equals("fallStatus")){
            if(dataValue.equals("0")){
                dataValue = "未跌倒";
            }else if(dataValue.equals("1")){
                dataValue = "跌倒";
            }else{
                dataValue = "无";
            }
        }
        map.put("key", dataKey);
        map.put("value", dataValue);
        messageListener.messagingTemplate.convertAndSendToUser("radars", "/message", map);
//        if(dataKey.equals("heartRateWave") || dataKey.equals("breathWave")){
//            Map<String, Object> testMap = new HashMap<>();
//            testMap.put("deviceCode", deviceCode);
//            testMap.put("key", dataKey);
//            testMap.put("value", dataValue);
//            messageListener.messagingTemplate.convertAndSendToUser("test", "/message", testMap);
//        }
    }
}
